<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>日历</title>
	</head>
	<style>
		.calendar-form{
			margin-left: 100px;
			margin-top: 200px;
		}
		.calender-header{
			width: 100%;
			height: 100%;
			display: inline-flex;
			justify-content: space-between;
			align-items:center;
			box-sizing: border-box;
		}
		.calender-left{
			height: 14px;
			text-align: left;
			display: inline-flex;
			box-sizing: border-box;
		}
		.calender-left span{
			margin-right: 10px;
		}
		.calender-right{
			height: 14px;
			text-align: right;
			display: inline-flex;
			box-sizing: border-box;
		}
		.calender-right span{
			margin-left: 10px;
		}
		.calender-center{
			text-align: center;
		}
		.calendar-div{
			width: 300px;
			box-sizing: border-box;
			padding: 8px;
			box-shadow: 0 1px 3px hsl(0deg 0% 7% / 10%);
		}
		
		.calendar-div::before{
			content: '';
			display: block;
			position: absolute;
			width: 10px;
			height: 10px;
			top: -6px;
			left: 10px;
			transform: rotate(-45deg);
			background-color: white;
			border: 1px;
			border-style: solid;
			border-color: #e4e7ed #e4e7ed transparent transparent;
		}
		.calendar{
			background-color: #fff;
			border-collapse: collapse;
			border: 1px solid transparent;
			width: 100%;
			height: 200px;
			user-select: none;
		}
		.prev-month{
			color: rgba(194, 194, 194, 1);
		}
		.next-month{
			color: rgba(194, 194, 194, 1);
		}
		.current-month{
			color: rgb(51, 54, 57);
		}
		.week-tr{
			height: 40px;
			border-bottom: 1px solid black;
			color: rgb(51, 54, 57);
		}
		.week-td{
			width: 25px;
			height: 24px;
			padding: 2px 0px 0px 3px;
			text-align: center;
			color: rgb(51, 54, 57);
		}
		.day {
			width: 24px;
			height: 24px;
			padding: 10px;
			border: 1px solid rgb(239, 239, 245);
			text-align: center;
		}
		.day:hover{
			background-color: rgb(243, 243, 245);
		}
		.current{
			background-color: #2d8cf0;
		}
		.calender-button{
			width: 100%;
			height: 100%;
			display: inline-flex;
			justify-content: right;
			align-items: center;
		}
		.calender-button button{
			margin: 3px 3px;
			background-color: #fff;
			border: 1px solid rgb(239, 239, 245);
			border-radius: 3px;
		}
		.calender-button button:hover{
			border: 1px solid #2d8cf0;
		}
		.calendar-input{
			width: 300px;
			height: 23px;
			border: 1px solid #2d8cf0;
			outline: none;
			padding: 2px;
			border-radius: 4px;
			color: #75849a;
		}
	</style>
	<body>
		<div class="calendar-form">
			<label>选择日历</label>
			<input class="calendar-input" />
		</div>
		
		<script>
			
			//创建节点到页面
			createDom();
			let calendar=document.getElementsByClassName('calendar-input')[0];
			let calendarDiv=document.getElementsByClassName('calendar-div')[0];
			//将两个节点关联在一起
			association(calendar,calendarDiv)
			
			// 获取当前日期
			var currentDate = new Date();
			
			function now(){
				currentDate = new Date();
				renderCalendar(currentDate,'calendar')
				calendar.value=currentDate.toISOString().split("T")[0]
			}
			
			function clearDate(){
				calendar.value='';
			}
			
			//上一年
			function previousYear(){
				currentDate.setFullYear(currentDate.getFullYear() - 1); // 将年份减去1
				renderCalendar(currentDate,'calendar')
			}
			
			function nextYear(){
				currentDate.setFullYear(currentDate.getFullYear() + 1); // 将年份减去1
				renderCalendar(currentDate,'calendar')
			}
			
			function previousMonth(){
				var currentMonth = currentDate.getMonth(); // 获取当前月份
				
				if (currentMonth === 0) { // 如果当前月份是一月
				  currentDate.setFullYear(currentDate.getFullYear() - 1); // 将年份减去1
				  currentDate.setMonth(11); // 设置月份为十二月
				} else {
				   currentDate.setMonth(currentMonth - 1); // 将月份减去1
				}
				renderCalendar(currentDate,'calendar');
			}
			
			function nextMonth(){
				var currentMonth = currentDate.getMonth(); // 获取当前月份
				
				if (currentMonth === 11) { // 如果当前月份是一月
				  currentDate.setFullYear(currentDate.getFullYear() + 1); // 将年份减去1
				  currentDate.setMonth(0); // 设置月份为十二月
				} else {
				   currentDate.setMonth(currentMonth + 1); // 将月份减去1
				}
				renderCalendar(currentDate,'calendar');
			}
			
			
			
			renderCalendar(currentDate,'calendar')
			
			function renderCalendar(currentDate,id){
				let day=currentDate.getDate();
				
				// 获取当前年份
				var currentYear = currentDate.getFullYear();
				
				// 获取当前月份
				var currentMonth = currentDate.getMonth();
				
				// 创建一个包含每个月份的名称的数组
				var months = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
				
				// 创建一个包含每个星期的名称的数组
				var weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
				
				// 获取当前月份的第一天
				var firstDay = new Date(currentYear, currentMonth, 1);
				
				// 获取当前月份的最后一天
				var lastDay = new Date(currentYear, currentMonth + 1, 0);
				
				// 创建日历表格
				var calendar = "<table class='calendar'>";
				
				// 添加表头行
				calendar += "<tr><td colspan='7'><div class='calender-header'>";
				calendar+='<span class="calender-left">';
				calendar+='		<span onclick="previousYear()"><svg  width="14" height="14" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g fill="currentColor" fill-rule="nonzero"><path d="M8.73171,16.7949 C9.03264,17.0795 9.50733,17.0663 9.79196,16.7654 C10.0766,16.4644 10.0634,15.9897 9.76243,15.7051 L4.52339,10.75 L17.2471,10.75 C17.6613,10.75 17.9971,10.4142 17.9971,10 C17.9971,9.58579 17.6613,9.25 17.2471,9.25 L4.52112,9.25 L9.76243,4.29275 C10.0634,4.00812 10.0766,3.53343 9.79196,3.2325 C9.50733,2.93156 9.03264,2.91834 8.73171,3.20297 L2.31449,9.27241 C2.14819,9.4297 2.04819,9.62981 2.01448,9.8386 C2.00308,9.89058 1.99707,9.94459 1.99707,10 C1.99707,10.0576 2.00356,10.1137 2.01585,10.1675 C2.05084,10.3733 2.15039,10.5702 2.31449,10.7254 L8.73171,16.7949 Z"></path></g></g></svg></span>';
				calendar+='		<span onclick="previousMonth()"><svg  width="14" height="14" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12.2674 15.793C11.9675 16.0787 11.4927 16.0672 11.2071 15.7673L6.20572 10.5168C5.9298 10.2271 5.9298 9.7719 6.20572 9.48223L11.2071 4.23177C11.4927 3.93184 11.9675 3.92031 12.2674 4.206C12.5673 4.49169 12.5789 4.96642 12.2932 5.26634L7.78458 9.99952L12.2932 14.7327C12.5789 15.0326 12.5673 15.5074 12.2674 15.793Z" fill="currentColor"></path></svg></span>'
				calendar+='</span>';
				calendar+="<span class='calender-center'>"+ months[currentMonth] + " " + currentYear + "</span>"
				calendar+='<span class="calender-right">';
				calendar+='		<span onclick="nextMonth()"><svg  width="14" height="14" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7.73271 4.20694C8.03263 3.92125 8.50737 3.93279 8.79306 4.23271L13.7944 9.48318C14.0703 9.77285 14.0703 10.2281 13.7944 10.5178L8.79306 15.7682C8.50737 16.0681 8.03263 16.0797 7.73271 15.794C7.43279 15.5083 7.42125 15.0336 7.70694 14.7336L12.2155 10.0005L7.70694 5.26729C7.42125 4.96737 7.43279 4.49264 7.73271 4.20694Z" fill="currentColor"></path></svg></span>'
				calendar+='		<span onclick="nextYear()"><svg  width="14" height="14" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g fill="currentColor" fill-rule="nonzero"><path d="M11.2654,3.20511 C10.9644,2.92049 10.4897,2.93371 10.2051,3.23464 C9.92049,3.53558 9.93371,4.01027 10.2346,4.29489 L15.4737,9.25 L2.75,9.25 C2.33579,9.25 2,9.58579 2,10.0000012 C2,10.4142 2.33579,10.75 2.75,10.75 L15.476,10.75 L10.2346,15.7073 C9.93371,15.9919 9.92049,16.4666 10.2051,16.7675 C10.4897,17.0684 10.9644,17.0817 11.2654,16.797 L17.6826,10.7276 C17.8489,10.5703 17.9489,10.3702 17.9826,10.1614 C17.994,10.1094 18,10.0554 18,10.0000012 C18,9.94241 17.9935,9.88633 17.9812,9.83246 C17.9462,9.62667 17.8467,9.42976 17.6826,9.27455 L11.2654,3.20511 Z"></path></g></g></svg></span>';
				calendar+='</span>';
				calendar+="</div></td></tr>";
				// 添加星期行
				calendar += "<tr class='week-tr'>";
				for (var i = 0; i < weekdays.length; i++) {
				  calendar += "<td class='week-td'>" + weekdays[i] + "</td>";
				}
				calendar += "</tr>";
				
				var prevMonthLast= new Date(currentYear, currentMonth, 0);
				// 获取上个月的最后一天
				var prevMonthLastDay = prevMonthLast.getDate();
				
				// 获取每个月第一天是星期几
				var firstDayOfWeek = firstDay.getDay();
				if (firstDayOfWeek === 0) {
				   firstDayOfWeek = 7;  // 如果是星期日，则将其转换为7
				}
				
				// 添加日期行
				var dayCounter = 1; // 计数器，用于累加日期
				
				// 添加日期行
				for (var row = 1; row <= 6; row++) {
				  calendar += "<tr>";
				
				  for (var col = 0; col < 7; col++) {
				    if (row === 1 && col < firstDayOfWeek) {
				         // 添加上个月的日期
				         var prevMonthDate = prevMonthLastDay - firstDayOfWeek + col + 1;
				         let year=getYear(currentDate,false)
				         let month=getMonth(currentDate,false)+1;
						 calendar += "<td onclick='getDay(this)'  year="+year+" month="+month+" day="+prevMonthDate+"  class='prev-month day'>" + prevMonthDate + "</td>";
				       } else if (dayCounter > lastDay.getDate()) {
				         // 添加下个月的日期
				         var nextMonthDate = dayCounter - lastDay.getDate();
						 let year=getYear(currentDate,true)
						 let month=getMonth(currentDate,true)+1;
				         calendar += "<td onclick='getDay(this)'  year="+year+" month="+month+" day="+nextMonthDate+" class='next-month day'>" + nextMonthDate + "</td>";
				         dayCounter++;
				       } else {
						 if(dayCounter==day){
							 // 添加当前月的日期
							 let month=currentMonth+1;
							 calendar += "<td onclick='getDay(this)'  year="+currentYear+" month="+month+" day="+dayCounter+" class='current-month current day'>" + dayCounter + "</td>";
						 }else{
							 // 添加当前月的日期
							 let month=currentMonth+1;
							 calendar += "<td onclick='getDay(this)'  year="+currentYear+" month="+month+" day="+dayCounter+" class='current-month  day'>" + dayCounter + "</td>";
						 }
				         dayCounter++;
				       }
				  }
				
				  calendar += "</tr>";
				}
				calendar += "<tr class='last-tr'><td colspan='7'>";
				calendar +="	<div class='calender-button'>";
				calendar +="		<button onclick='clearDate()'>清除</button>"
				calendar +="		<button onclick='now()'>此刻</button>"
				calendar +="	</div>";
				calendar += "</td></tr>";
				
				// 关闭表格
				calendar += "</table>";
				
				
				document.getElementById(id).innerHTML=calendar;
			}
			
			function getYear(curentDate,isNext){
				var currMonth = curentDate.getMonth(); // 获取当前月份
				if(isNext){
					if (currMonth === 11) { // 如果当前月份是一月
						return curentDate.getFullYear() + 1;
					} else {
						return curentDate.getFullYear();
					}
				}else{
					if (currMonth === 0) { // 如果当前月份是一月
						return curentDate.getFullYear() - 1;
					} else {
						return curentDate.getFullYear();
					}
				}
			}
			
			function getMonth(curentDate,isNext){
				var currMonth = curentDate.getMonth(); // 获取当前月份
				if(isNext){
					if (currMonth === 11) { // 如果当前月份是一月
						return 1;
					} else {
						return currMonth + 1;
					}
				}else{
					if (currMonth === 0) { // 如果当前月份是一月
						return 11;
					} else {
						return currMonth - 1;
					}
				}
			}
			
			function association(target,source){
				source.style.position='absolute';
				source.style.display='none';
				target.addEventListener('click',()=>{
					source.style.display = 'block';
					// source.style.width = target.offsetWidth +"px";
					source.style.left = target.offsetLeft + "px";
					source.style.top = target.offsetTop + target.offsetHeight+ 10 + "px";
				})
				
				
				
				document.addEventListener('click', function(event) {
					  var sourceDivRect = source.getBoundingClientRect(); // 获取该div元素相对于视口的位置信息
					  var targetDivRect = target.getBoundingClientRect();
					  var mouseX = event.clientX; // 获取鼠标当前位置的x坐标
					  var mouseY = event.clientY; // 获取鼠标当前位置的y坐标
					  if (mouseX >= sourceDivRect.left && mouseX <= sourceDivRect.right && mouseY >= sourceDivRect.top && mouseY <= sourceDivRect.bottom) {
							console.log('鼠标在div区域内');
					  } else if( mouseX >= targetDivRect.left && mouseX <= targetDivRect.right && mouseY >= targetDivRect.top && mouseY <= targetDivRect.bottom){
						    console.log('鼠标在div区域内');
					  } else {
							console.log('鼠标在div不在区域内');
						    source.style.display = 'none';
					  }
				});
			}
			
		
			function createDom(){
				var newNode = document.createElement("div");
				newNode.classList.add('calendar-div');
				
				var newNode2 = document.createElement("div");
				newNode2.id="calendar";
				
				newNode.appendChild(newNode2);
				// 将节点添加到body上
				document.body.appendChild(newNode);
			}
			
			function getDay(e){
				let year=e.getAttribute('year');
				let month=e.getAttribute('month');
				let day=e.getAttribute('day');
				month=month;
				if(month.length==1){
					month='0'+month;
				}
				if(day.length==1){
					day='0'+day;
				}
				let  dateday=year+'-'+month+'-'+day;
				calendar.value=dateday;
			}
			
		
		
			
		</script>
	</body>
</html>